﻿using System;
using System.Net;
using System.Threading.Tasks;

using Renci.SshNet;

namespace SSHAgent
{
    class SSHAgent : IDisposable
    {
        private readonly ConnectionInfo conInfo;
        private readonly SshClient sshClient;
        public SSHAgent(string sshHost, string sshPwd, string sshUser, int sshPort = 22)
        {
            var auth = new PasswordAuthenticationMethod(sshUser, sshPwd);

            conInfo = new ConnectionInfo(sshHost, sshPort, sshUser, auth);

            sshClient = new SshClient(conInfo);
        }

        public event Action OnClose;

        public bool Connect(out string msg)
        {
            msg = "";
            if (sshClient.IsConnected)
            {
                return true;
            }
            try
            {
                sshClient.Connect();

                if (!sshClient.IsConnected)
                {
                    return false;
                }

                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        while (sshClient.IsConnected)
                        {
                            System.Threading.Thread.Sleep(5000);
                            sshClient.CreateCommand("date").Execute();
                        }
                    }
                    catch
                    {
                        OnClose?.Invoke();
                    }
                }, TaskCreationOptions.LongRunning);
                return true;
            }
            catch (Renci.SshNet.Common.SshAuthenticationException e)
            {
                msg = "授权失败，或密码错误";
                return false;
            }
            catch (Renci.SshNet.Common.SshConnectionException e)
            {
                msg = "连接失败，请检查地址或网络";
                return false;
            }
            catch (Exception e)
            {
                msg = "连接失败，请检查地址或网络";
                return false;
            }
        }



        public bool Agent(uint remotePort, uint localPort)
        {
            try
            {
                var local = IPAddress.Loopback.ToString();
                ForwardedPortLocal port = new ForwardedPortLocal(local, localPort, local, remotePort);
                //给客户端追加需要转发的端口信息
                sshClient.AddForwardedPort(port);
                //启动
                port.Start();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        public void Dispose()
        {
            if (sshClient.IsConnected)
                sshClient.Disconnect();
            sshClient.Dispose();
        }
    }
}
